package net.sf.brutil.v0.light;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;


public class CollectionUtil {


	public static List<String> string2list(String file2string) {
		return Arrays.asList(file2string.split("\n"));
	}
	
	static public  String list2String(Collection<?> list,String newLine){
		return list2String(list, newLine,false,true);
	}
	static public  String list2String(Collection<?> list,String newLine,boolean showIndexes,boolean insertFirstNewLine){
		StringBuilder builder=new StringBuilder();
		int index=0;
		for(Object object:list){
			if ((insertFirstNewLine && index==0) || index>0)
				builder.append(newLine);
			if (showIndexes){
				builder.append(index);
				builder.append(" ");
			}
				
			builder.append(ObjectUtil.toStringOrNull(object));
			index++;
		}
		return builder.toString();
	}

	
	
	

	public static <T> List<String> stringifyList (List<T> elements,ToStringifier<T> toStringifier){
		List<String> retVal=new ArrayList<String>();
		for(T element:elements)
			retVal.add(toStringifier.toString(element));
		return retVal;
		
	}
	
	
	
	  public static <T> int indexOf(T[] stack,T needle){
	        for(int index=0;index<stack.length;index++){
	            if (ObjectUtil.equals(needle, stack[index]))
	                    return index;
	                    
	        }
	        return -1;
	    }
	  
	  public static <T> List<T> addOrCreate(List<T> existingFilters,
				T ...filters) {
			
			if (existingFilters==null)
				existingFilters=new LinkedList<T>();
			for(T filter:filters)
				existingFilters.add(filter);
			return existingFilters;
		}
	  
	  
	    public static String map2String(Map<String, ?> map) {
	        StringBuffer retVal=new StringBuffer();
	        for(Object key:map.keySet()){
	            Object value=map.get(key);
	            if (value==null)
	                retVal.append("#"+key+"="+value+"\n");
	            else
	                retVal.append(key+"="+EscapeUtil.escapeProperty(value.toString())+"\n");
	        }
	        return retVal.toString();
	    }
	    

	    public static Map<String, String> string2map(String mapAsString) {
	    
	        //Properties properties=new Properties();
	        Map<String, String> retVal=new HashMap<String, String>();
	        if (mapAsString!=null)
	        try{
	            //properties.load(new CharArrayReader(mapAsString.toCharArray()));
	            //return (Map)properties;
	            
	            
	            String lines[]=mapAsString.split("\n");
	            for(String line:lines){
	              if (line.trim().startsWith("#")) // comment
	                  continue;
	              if (line.trim().length()==0) // empty line
	                  continue;
	              int sepIndex=line.indexOf("=");
	              
	              if (sepIndex==-1) sepIndex=line.indexOf(":");
	              if (sepIndex==-1)
	                  throw new RuntimeException("can not find : or = in "+line);
	                  
	              String key=line.substring(0,sepIndex).trim();
	              String value=line.substring(sepIndex+1);
	              retVal.put(key,value);
	              
	            }
	        } catch (Exception e){
	            throw new RuntimeException(e);
	        }
	        return retVal;
	    }
	    
	    public static <T>Map<T, T> list2map(List<T> list) {
			
			Map<T, T> retVal=new LinkedHashMap<T,T>();
			for(int i=0;i<list.size();i+=2){
				retVal.put(list.get(i), list.get(i+1));
			}
			return retVal;
		}
		
		public static <T>Map<T, T> array2map(T...objects) {
			return list2map(Arrays.asList(objects));
		}
		public static <E> Pair<E,E> list2pair(List<E> values){
	        if (values.size()!=2) 
	            throw new IllegalArgumentException("can not convert to pair "+values);
	        return new Pair<E,E> (values.get(0),values.get(1));
	    }
		
		
		
		
		
		
		
		public static <T>List<List<T>> rotate(List<List<T>> values){
	        List<List<T>>  retVal=new ArrayList<List<T>>();
	        int x=values.get(0).size();
	        int y=values.size();
	        for(int i=0;i<x;i++){
	            List<T> row=new ArrayList<T>();
	            for(int j=0;j<y;j++){
	                row.add(values.get(j).get(i));
	            }
	            retVal.add(row);
	        }
	        return  retVal;
	    }


	    public static <K,V> Map<V,K> inverseMap(Map<K,V> map){
	        HashMap<V,K> retVal=new HashMap<V, K>();
	        for(Entry<K,V> entry:map.entrySet())
	            retVal.put(entry.getValue(), entry.getKey());
	        return retVal;
	    }
	    
		
		
		
		
		
		
		
}
